package cn.codelab.springcloudalibaba.step06.controller;

import cn.codelab.springcloudalibaba.step06.exception.ExceptionUtil;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Seven
 * @description
 * @Gitee https://gitee.com/it-codelab
 * @Copyright 公众号：Seven的代码实验室
 */
@RestController
@RequestMapping("/user")
public class UserController {

    @SentinelResource(value = "getUserById", blockHandler = "exceptionHandler", fallback = "getUserByIdFallback")
    @RequestMapping("/{id}")
    public String getUserById(@PathVariable Long id) {
        // 模拟从数据库中查找用户信息
        Map<Long, String> map = new HashMap<>(0);
        map.put(1L, "user1");
        map.put(2L, "user3");
        map.put(3L, "user3");
        return map.get(id);
    }

    // Fallback函数，函数签名与原函数一致或加一个Throwable类型的参数.
    public String getUserByIdFallback(Long s, Throwable throwable) {
        return String.format("Halooooo %d", s);
    }

    // Block异常处理函数，参数最后多一个BlockException，其余与原函数一致.
    public String exceptionHandler(Long s, BlockException ex) {
        // Do some log here.
        ex.printStackTrace();
        return "===被流控了=== " + s;
    }

    // 这里单独演示 blockHandlerClass 的配置.
    // 对应的 `handleException` 函数需要位于 `ExceptionUtil` 类中，并且必须为 public static 函数.
    @SentinelResource(value = "test", blockHandler = "handleException", blockHandlerClass = {ExceptionUtil.class})
    public void test() {
        System.out.println("Test");
    }
}
